package com.zj.docker.websocket;

import com.zj.docker.client.UserClient;
import com.zj.docker.utils.JsonUtils;

import com.zj.docker.utils.SpringBeanFactoryUtils;
import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;


/**
 * WebSocket服务
 * @author zj
 * @since 2018/12/9 16:08
 */
@ServerEndpoint(value = "/ws/{userId}")
@Component
@Slf4j
public class WebSocketServer {

//    @Autowired   注意这里自动注入失效
//    UserClient userClient;

    //用来存放每个客户端对应的MyWebSocket对象。
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;

    //来储存用户的id
    private String userId;

    private static HashMap<String, Session> mapmap = new HashMap<>();



    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String  userId) {
        this.session = session;
        this.userId=userId;

        mapmap.put(session.getId(), session);//绑定，并保存
        webSocketSet.add( this );

        try {
            UserClient userClient = SpringBeanFactoryUtils.getBean( UserClient.class );

            //将sessionId保存到数据库中
            userClient.SaveOrUpdateUser( session.getId(), Integer.valueOf( userId ) );
        }catch (Exception e){
            log.error( "调用user服务出现异常：{}",e.getMessage() );
        }

        System.out.println("有新连接加入:"+userId+",当前在线人数为" + webSocketSet.size());
        System.out.println( "频道号："+session.getId() );
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("userId") String userId) {
        webSocketSet.remove( this );//从set中删除
        System.out.println("有一连接关闭:"+userId+"!  , 当前在线人数为" + webSocketSet.size());

    }

    /**
     * 连接出错调用的方法
     */
    @OnError
    public void onError(Throwable error) {
        log.error("WebSocket连接出错");
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 消息内容
     */
    @OnMessage
    public void onMessage(String message,@PathParam("userId") String userId) {
//        log.info("{}({})：{}",this.session.getId(), format.format(new Date()), message);

        System.out.println( message );
        try {
            Map<String, String> map = new HashMap<>(16);
            map.put("info", "heart");
            sendMessage( JsonUtils.objectToJson(map), this.session.getId());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送消息(单聊)
     * @author zj
     * @since 2018/12/9 16:55
     */
    public void sendMessage(String message, String sessionId) throws IOException {
//        Session session = webSocketSet.get(sessionId);
        Session session = mapmap.get( sessionId );
        if(session != null) {
//            session.getBasicRemote().sendText(message);
            session.getAsyncRemote().sendText( message );//异步发消息
        } else {
            throw new IOException("WebSocket连接中断");
        }
    }



    /**
     *   //群发消息（多聊）
     * @param message 发送消息内容
     */
    public void broadcast(String message){
        for (WebSocketServer item : webSocketSet) {
            //同步异步说明参考：http://blog.csdn.net/who_is_xiaoming/article/details/53287691
            //this.session.getBasicRemote().sendText(message);
            item.session.getAsyncRemote().sendText(message);//异步发送消息.
        }
    }

}
